/**
 * 
 */
package com.da.finance;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.collections.map.ListOrderedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.googlecode.cswish.annotation.Rest;
import com.googlecode.cswish.oosearch.QLInfo;
import com.googlecode.cswish.struts.spring.GenericService;
import com.ra.landlord.LandlordUser;
import com.ra.landlord.LandlordUserService;
import com.ra.util.DateTimeUtil;

/**
 * 财务收入支出统计服务
 * @author colin
 * @date 2015年6月15日
 */
@Service
public class FinanceStatisticsService {

	@Resource
	private GenericService genericService;
	
	@PersistenceContext(unitName = "espirit")
	protected EntityManager em;
	
	@Autowired
	private LandlordUserService landlordUserService;
	
	@SuppressWarnings("unchecked")
	private static Map<String, String> sysModule = ListOrderedMap.decorate(new HashMap<String, String>());
	static {
		sysModule.put("0_装修", "支出-装修");
		sysModule.put("0_房租", "支出-房租");
		sysModule.put("0_自定义", "支出-自定义");
		
		sysModule.put("0_押金", "支出-押金");
		sysModule.put("0_维修", "支出-维修");
		sysModule.put("0_退租", "支出-退租");
		
		sysModule.put("1_房租", "收入-房租");
		sysModule.put("1_押金", "收入-押金");
		//sysModule.put("1_其他", "收入-其他");
		sysModule.put("1_自定义", "收入-自定义");
		
		
	}
	
	/**
	 * 系统模块统计分析
	 * @param type
	 * @param year
	 * @return
	 */
	public Map<String, BigDecimal[]> analyse(int monthCount) {
		return genericAnalyse(monthCount, sysModule);
	}
	
	/**
	 * 通用模块访问统计分析
	 * @param monthCount
	 * @param module
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Map<String, BigDecimal[]> genericAnalyse(int monthCount, Map<String, String> module){
		
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 0);
    	calendar.set(Calendar.MINUTE, 0);
    	calendar.set(Calendar.SECOND, 0);
    	calendar.add(Calendar.MONTH, -monthCount+1);
    	calendar.set(Calendar.DAY_OF_MONTH,1);
    	
    	Calendar today = Calendar.getInstance();
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    	try {
			today.setTime(sdf.parse(sdf.format(today.getTime())));
			today.add(Calendar.MONTH, 1);
			today.set(Calendar.DAY_OF_MONTH, 1);
			today.add(Calendar.SECOND, -1);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		//ql查询日志一年以内的记录
		String ql = "select a from " + DaFinanceStatement.class.getName() + " a where a.tradeDate >= ? and a.tradeDate<=? and a.status = ?";
		QLInfo qlInfo = new QLInfo(ql, false, calendar.getTime(), today.getTime(), 1);
		
		List<DaFinanceStatement> financeStatements = genericService.searchByQl(qlInfo, false).getData();
		
		Map<String, BigDecimal[]> dataMap = getDataMap(monthCount, module);
		if (financeStatements != null && financeStatements.size() > 0) {
			Calendar tempCalendar = Calendar.getInstance();
			for (DaFinanceStatement financeStatement : financeStatements) {
				
				Date tradeDate = financeStatement.getTradeDate();
				tempCalendar.setTime(tradeDate);
				//待定
				int curNum = tempCalendar.get(Calendar.MONTH)- calendar.get(Calendar.MONTH);
				
				if (calendar.get(Calendar.YEAR) != tempCalendar.get(Calendar.YEAR)) {
					curNum += 12*(tempCalendar.get(Calendar.YEAR) - calendar.get(Calendar.YEAR));
				}
				String paymentCategory = financeStatement.getFinanceCategory().getPaymentCategory().toString();
				String tradeCategory = financeStatement.getFinanceCategory().getTradeCategory();
				String curKey = paymentCategory+"_"+tradeCategory;
				boolean isMatch = false;
				for (String pathKey : dataMap.keySet()) {
					if (curKey.contains(pathKey)) {
						BigDecimal[] value = dataMap.get(pathKey);
						addValue(financeStatement, curNum, value);
						isMatch = true;
					}
				}
				
				if (isMatch) {
					continue;
				}
				
				//判断是由入还是支出
				if ("0".equals(paymentCategory)) {
					BigDecimal[] value = dataMap.get("0_自定义");
					addValue(financeStatement, curNum, value);
				}else if ("1".equals(paymentCategory)) {
					BigDecimal[] value = dataMap.get("1_自定义");
					addValue(financeStatement, curNum, value);
				}
				
			}
		}
		return merageDataMap(module, dataMap);
	}

	private void addValue(DaFinanceStatement financeStatement, int curNum,
			BigDecimal[] value) {
		if (value[curNum] == null) {
			value[curNum] = financeStatement.getTradeMoney();
		}else{
			value[curNum] = value[curNum].add(financeStatement.getTradeMoney());
		}
	}
	
	public static void main(String[] args) {
		
		Calendar calendar_now = Calendar.getInstance();
		
		Calendar calendar_before = Calendar.getInstance();
		calendar_before.add(Calendar.MONTH, -12);
		List<String> categories = new ArrayList<>();
		while (calendar_before.compareTo(calendar_now) < 0) {
	    	calendar_before.add(Calendar.MONTH, 1);
	    	categories.add(calendar_before.get(Calendar.YEAR)+"-"+(calendar_before.get(Calendar.MONTH)+1));
		}
		
		for (String str : categories) {
			System.out.println(str);
		}
		
		
		if(true){
			return ;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.set(2014, 5, 1);
//		calendar.set(Calendar.HOUR_OF_DAY, 0);
//    	calendar.set(Calendar.MINUTE, 0);
//    	calendar.set(Calendar.SECOND, 0);
//    	calendar.add(Calendar.MONTH, -12+2);
//    	calendar.set(Calendar.DAY_OF_MONTH,1);
    	
    	Calendar calendar2 = Calendar.getInstance();
    	calendar2.set(2015, 1, 15);
    	
    	System.out.println(calendar.get(Calendar.YEAR)+"-"+calendar.get(Calendar.MONTH)+"-"+calendar.get(Calendar.DATE));
    	System.out.println(calendar2.get(Calendar.YEAR)+"-"+calendar2.get(Calendar.MONTH)+"-"+calendar2.get(Calendar.DATE));
    	
    	
    	int curNum = 0;
		curNum = calendar2.get(Calendar.MONTH) - calendar.get(Calendar.MONTH);
		if (calendar.get(Calendar.YEAR) != calendar2.get(Calendar.YEAR)) {
			curNum += 12*(calendar2.get(Calendar.YEAR) - calendar.get(Calendar.YEAR));
		}
    	
    	
    	//result == 0 ? 12 : Math.abs(result);
    	System.out.println(curNum);
	}
	
	/**
	 * 合并模块访问统计数据
	 * @param data
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Map<String, BigDecimal[]> merageDataMap(Map<String, String> keyData, Map<String, BigDecimal[]> valueData){
		Map<String, BigDecimal[]> newDataMap = ListOrderedMap.decorate(new HashMap<String, Object>());
		for (String key : valueData.keySet()) {
			String newKey = keyData.get(key);
			BigDecimal[] dataValue = valueData.get(key);
			BigDecimal[] newDataValue = newDataMap.get(newKey);
			if (newDataValue == null) {
				newDataMap.put(newKey, valueData.get(key));
			}else{
				for (int i = 0; i < newDataValue.length; i++) {
					newDataValue[i] = newDataValue[i].add(dataValue[i]);
				}
			}
		}
		
		//TODO 对map进行排序，让收入的与支出的统一起来
		return newDataMap;
	}
	
	/**
	 * 获取横轴坐标值
	 * @param monthCount 提前几个月；
	 * @return
	 */
	@Rest(type="search")
	public Object[] getCategories(int monthCount){
		Calendar calendar_now = Calendar.getInstance();
		Calendar calendar_before = Calendar.getInstance();
		calendar_before.add(Calendar.MONTH, -monthCount);
		List<String> categories = new ArrayList<>();
		while (calendar_before.compareTo(calendar_now) < 0) {
	    	calendar_before.add(Calendar.MONTH, 1);
	    	categories.add(calendar_before.get(Calendar.YEAR)+"-"+(calendar_before.get(Calendar.MONTH)+1));
		}
		
		return categories.toArray();
	}
	

	/**
	 * 获取统计横坐标值
	 * @param dayCount
	 * @return
	 */
	@Rest(type="search")
	public String[] getAppCategories(int dayCount){
		String[] arrDate = new String[dayCount];
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, - dayCount);
		for (int i = 0; i < dayCount; i++) {
			arrDate[i] = DateTimeUtil.getDate(calendar);
			calendar.add(Calendar.DATE, 1);
			
		}
		return arrDate;
	}
	
	/**
	 * 获取初始化数据
	 * @param monthCount
	 * @param module
	 * @return
	 */
	private Map<String, BigDecimal[]> getDataMap(int monthCount, Map<String, String> module){
		Map<String, BigDecimal[]> dataMap = new HashMap<>();
		for (String keyPath : module.keySet()) {
			BigDecimal[] data = new BigDecimal[monthCount];
			for (int i = 0; i < data.length; i++) {
				data[i] = new BigDecimal(0);
			}
			dataMap.put(keyPath, data);
		}
		return dataMap;
	}
	
	public FinanceVO [] getFinanceByYear(Integer year) {
		FinanceVO [] finances = new FinanceVO[13];
		for (int i = 0; i< finances.length; i++) {
			finances[i] = new FinanceVO();
		}
		String sql = "select month(a.tradeDate), sum(case when (b.paymentCategory = 1 and a.tradeMoney < 0) or (b.paymentCategory = 0 and a.tradeMoney < 0) then a.tradeMoney*-1 else a.tradeMoney end), case when (b.paymentCategory = 1 and a.tradeMoney >= 0) or (b.paymentCategory = 0 and a.tradeMoney <= 0) then 1 else 0 end moneyType from da_dafinancestatement a "
				+ "inner join da_dafinancecategory b on a.financeCategory_id = b.id and year(a.tradeDate) = ? and a.landlordUser_user_id = ? and a.status = " + DaFinanceStatement.STATUS_VALID
				+ " group by month(a.tradeDate), moneyType";
		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		List result = em.createNativeQuery(sql)
				.setParameter(1, year)
				.setParameter(2, landlordUser.getOwnerUser().getId())
				.getResultList();
		for (Object row : result) {
 			Object [] rows = (Object[]) row; //支出类别，月份，金额
			
			int month = Integer.valueOf(rows[0].toString());
			BigDecimal money = BigDecimal.valueOf(Double.valueOf(rows[1].toString()));
			int paymentCategory = Integer.valueOf(rows[2].toString());
			
			if (paymentCategory == DaFinanceCategory.PAYMENT_CATEGORY_INCOME) {
				finances[month].setIncome(money);
			} else {
				finances[month].setExpend(money);
			}
		}
		BigDecimal yearIncome = BigDecimal.valueOf(0);
		BigDecimal yearExpend = BigDecimal.valueOf(0);
		for (int i = 1; i <= 12; i++) {
			yearIncome = yearIncome.add(finances[i].getIncome());
			yearExpend = yearExpend.add(finances[i].getExpend());
		}
		finances[0].setIncome(yearIncome);
		finances[0].setExpend(yearExpend);
		return finances;
	}
	
	public List<FinanceDetailVO> getFinanceMonthDetail(Integer year, Integer month) {
		String sql = "select b.id, b.`transaction`, b.tradeCategory, b.paymentCategory ,a.room_id, ifnull(d.`name`,''), ifnull(f.`name`,''), raRoom_room_id, ifnull(c.room_name, ''), ifnull(e.building_name, ''), DATE_FORMAT(a.tradeDate, '%Y-%m-%d'), sum(a.tradeMoney), e.buildings_id, f.id suiteId, b.type " 
					+ "from da_dafinancestatement a " 
					+ "inner join da_dafinancecategory b " 
					+ "on a.financeCategory_id = b.id and year(a.tradeDate) = ? and month(a.tradeDate) = ? and a.landlordUser_user_id = ? and a.status = " + DaFinanceStatement.STATUS_VALID 
					+ " left join ra_room c on a.raRoom_room_id = c.room_id " 
					+ "left join da_daroom d on a.room_id = d.id "
					+ "left join ra_building e on e.buildings_id = c.buildings_id "
					+ "left join da_dasuite f on f.id = d.suite_id "
					+ "group by DATE_FORMAT(a.tradeDate, '%Y-%m-%d'),a.id,a.raRoom_room_id, a.room_id "
					+ "order by DATE_FORMAT(a.tradeDate, '%Y-%m-%d') desc, c.buildings_id desc, d.suite_id desc, a.room_id asc, a.raRoom_room_id asc ";

		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		List result = em.createNativeQuery(sql)
				.setParameter(1, year)
				.setParameter(2, month)
				.setParameter(3, landlordUser.getOwnerUser().getId())
				.getResultList();
		List<FinanceDetailVO> financeDetails = new ArrayList<FinanceDetailVO>(result.size());
		for (Object row : result) {
			Object[] rows = (Object[]) row;
			FinanceDetailVO financeDetail = new FinanceDetailVO();
			financeDetail.setTransaction(rows[1].toString());
			financeDetail.setTradeCategory(rows[2].toString());
			financeDetail.setPaymentCategory(Integer.parseInt(rows[3].toString()));
			if (rows[4] != null) {
				financeDetail.setDaRoomId(Integer.parseInt(rows[4].toString()));
				financeDetail.setRoomName(rows[5].toString());
				financeDetail.setBuildingName(rows[6].toString());
				if (rows[13] != null) {
					financeDetail.setBuildingId(Integer.parseInt(rows[13].toString()));
				}
			} else if (rows[7] != null) {
				financeDetail.setRaRoomId(Integer.parseInt(rows[7].toString()));
				financeDetail.setRoomName(rows[8].toString());
				financeDetail.setBuildingName(rows[9].toString());
				if (rows[12] != null) {
					financeDetail.setBuildingId(Integer.parseInt(rows[12].toString()));
				}
			}
			financeDetail.setTradeDate(rows[10].toString());
			financeDetail.setTradeMoney(BigDecimal.valueOf(Double.valueOf(rows[11].toString())));
			financeDetail.setType(Integer.valueOf(rows[14].toString()));
			financeDetails.add(financeDetail);
		}
		return financeDetails;
	}
	
	public Map<Integer, List<FinancePercentVO>> getFinanceMonthPercentByYear(Integer year) {
		FinanceVO [] finances =  getFinanceByYear(year);
		String sql = "select month(a.tradeDate),b.id, b.`transaction`, b.tradeCategory, b.paymentCategory, sum(a.tradeMoney), b.type from da_dafinancestatement a " 
					+ "inner join da_dafinancecategory b " 
					+ "on a.financeCategory_id = b.id and year(a.tradeDate) = ? and a.landlordUser_user_id = ? and a.status = " + DaFinanceStatement.STATUS_VALID
					+ " group by month(a.tradeDate), b.id ";
		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		List result = em.createNativeQuery(sql)
				.setParameter(1, year)
				.setParameter(2, landlordUser.getOwnerUser().getId())
				.getResultList();
		List<FinancePercentVO> financePercents = new ArrayList<FinancePercentVO>(result.size());
		for (Object row : result) {
			Object[] rows = (Object[]) row;
			FinancePercentVO financePercent = new FinancePercentVO();
			financePercent.setMonth(Integer.parseInt(rows[0].toString()));
			financePercent.setCategoryId(Integer.parseInt(rows[1].toString()));
			financePercent.setTransaction(rows[2].toString());
			financePercent.setTradeCategory(rows[3].toString());
			financePercent.setPaymentCategory(Integer.valueOf(rows[4].toString()));
			financePercent.setTradeMoney(BigDecimal.valueOf(Double.parseDouble(rows[5].toString())));
			if (DaFinanceCategory.PAYMENT_CATEGORY_INCOME.equals(financePercent.getPaymentCategory())) {
				if (finances[financePercent.getMonth()].getIncome().compareTo(BigDecimal.ZERO) == 0) {
					financePercent.setPercent(BigDecimal.valueOf(0));
				} else {
					financePercent.setPercent(financePercent.getTradeMoney().divide(finances[financePercent.getMonth()].getIncome(), 10, RoundingMode.HALF_UP));
				}
			} else {
				if (finances[financePercent.getMonth()].getExpend().compareTo(BigDecimal.ZERO) == 0) {
					financePercent.setPercent(BigDecimal.valueOf(0));
				} else {
					financePercent.setPercent(financePercent.getTradeMoney().divide(finances[financePercent.getMonth()].getExpend(), 10, RoundingMode.HALF_UP));
				}
			}
			financePercent.setType(Integer.parseInt(rows[6].toString()));
			financePercents.add(financePercent);
		}
		Map<Integer, List<FinancePercentVO>> resultMap = new HashMap<Integer, List<FinancePercentVO>>();
		int month = -1;
		List<FinancePercentVO> financePercentList = null;
		for (FinancePercentVO financePercent : financePercents) {
			if (month != financePercent.getMonth()) {
				financePercentList = new ArrayList<FinancePercentVO>(4);
				financePercentList.add(financePercent);
				month = financePercent.getMonth();
				resultMap.put(month, financePercentList);
			} else {
				financePercentList.add(financePercent);
			}
		}
		return resultMap;
	}
	
	public List<FinancePercentVO> getFinanceYearPercent(Integer year) {
		FinanceVO [] finances =  getFinanceByYear(year);
		String sql = "select year(a.tradeDate),b.id, b.`transaction`, b.tradeCategory, b.paymentCategory, sum(a.tradeMoney), b.type from da_dafinancestatement a " 
					+ "inner join da_dafinancecategory b " 
					+ "on a.financeCategory_id = b.id and year(a.tradeDate) = ? and a.landlordUser_user_id = ? and a.status = " + DaFinanceStatement.STATUS_VALID 
					+ " group by b.id ";
		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		List result = em.createNativeQuery(sql)
				.setParameter(1, year)
				.setParameter(2, landlordUser.getOwnerUser().getId())
				.getResultList();
		List<FinancePercentVO> financePercents = new ArrayList<FinancePercentVO>(result.size());
		for (Object row : result) {
			Object[] rows = (Object[]) row;
			FinancePercentVO financePercent = new FinancePercentVO();
			financePercent.setMonth(Integer.parseInt(rows[0].toString()));
			financePercent.setCategoryId(Integer.parseInt(rows[1].toString()));
			financePercent.setTransaction(rows[2].toString());
			financePercent.setTradeCategory(rows[3].toString());
			financePercent.setPaymentCategory(Integer.valueOf(rows[4].toString()));
			financePercent.setTradeMoney(BigDecimal.valueOf(Double.parseDouble(rows[5].toString())));
			if (DaFinanceCategory.PAYMENT_CATEGORY_INCOME.equals(financePercent.getPaymentCategory())) {
				if (finances[0].getIncome().compareTo(BigDecimal.ZERO) == 0) {
					financePercent.setPercent(BigDecimal.valueOf(0));
				} else {
					financePercent.setPercent(financePercent.getTradeMoney().divide(finances[0].getIncome(), 10, RoundingMode.HALF_UP));
				}
			} else {
				if (finances[0].getExpend().compareTo(BigDecimal.ZERO) == 0) {
					financePercent.setPercent(BigDecimal.valueOf(0));
				} else {
					financePercent.setPercent(financePercent.getTradeMoney().divide(finances[0].getExpend(), 10, RoundingMode.HALF_UP));
				}
			}
			financePercent.setType(Integer.parseInt(rows[6].toString()));
			financePercents.add(financePercent);
		}
		return financePercents;
	}
	
	public List<FinanceDetailVO> getFinanceDetailByRange(Date start, Date end, Integer buildingId, Integer roomId, Integer financeCategoryId) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		StringBuilder sb = new StringBuilder();
		sb.append("select b.id, b.`transaction`, b.tradeCategory, b.paymentCategory ,a.room_id, ifnull(d.`name`,''), ifnull(f.`name`,''), raRoom_room_id, ifnull(c.room_name, ''), ifnull(e.building_name, ''), DATE_FORMAT(a.tradeDate, '%Y-%m-%d'), sum(a.tradeMoney) , e.buildings_id, f.id suiteId, b.type ");
		sb.append("from da_dafinancestatement a "); 
		sb.append("inner join da_dafinancecategory b ");
		sb.append("on a.financeCategory_id = b.id and a.landlordUser_user_id = ? and a.status = " + DaFinanceStatement.STATUS_VALID);
		sb.append(" left join ra_room c on a.raRoom_room_id = c.room_id ");
		sb.append("left join da_daroom d on a.room_id = d.id ");
		sb.append("left join ra_building e on e.buildings_id = c.buildings_id ");
		sb.append("left join da_dasuite f on f.id = d.suite_id ");
		sb.append("where 1 = 1");
		if (buildingId != null) {
			sb.append(" and ( e.buildings_id = " + buildingId + " or f.id = " + buildingId + " )");
		}
		if (roomId != null) {
			sb.append(" and ( c.room_id = " + roomId + " or d.id = " + roomId + " )");
		}
		if (financeCategoryId != null) {
			sb.append(" and b.id = " + financeCategoryId);
		}
		if (start != null) {
			sb.append(" and a.tradeDate >= '" + sdf.format(start) + "'");
		}
		if (end != null) {
			sb.append(" and DATE_FORMAT(a.tradeDate, '%Y-%m-%d') <= '" + sdf.format(end) + "'");
		}
		sb.append(" group by DATE_FORMAT(a.tradeDate, '%Y-%m-%d'),a.id,a.raRoom_room_id, a.room_id ");
		sb.append(" order by DATE_FORMAT(a.tradeDate, '%Y-%m-%d') desc, c.buildings_id desc, d.suite_id desc, a.room_id asc, a.raRoom_room_id asc ");
		
		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		List result = em.createNativeQuery(sb.toString())
				.setParameter(1, landlordUser.getOwnerUser().getId())
				.getResultList();
		List<FinanceDetailVO> financeDetails = new ArrayList<FinanceDetailVO>(result.size());
		for (Object row : result) {
			Object[] rows = (Object[]) row;
			FinanceDetailVO financeDetail = new FinanceDetailVO();
			financeDetail.setTransaction(rows[1].toString());
			financeDetail.setTradeCategory(rows[2].toString());
			financeDetail.setPaymentCategory(Integer.parseInt(rows[3].toString()));
			if (rows[4] != null) {
				financeDetail.setDaRoomId(Integer.parseInt(rows[4].toString()));
				financeDetail.setRoomName(rows[5].toString());
				financeDetail.setBuildingName(rows[6].toString());
				if (rows[13] != null) {
					financeDetail.setBuildingId(Integer.parseInt(rows[13].toString()));
				}
			} else if (rows[7] != null) {
				financeDetail.setRaRoomId(Integer.parseInt(rows[7].toString()));
				financeDetail.setRoomName(rows[8].toString());
				financeDetail.setBuildingName(rows[9].toString());
				if (rows[12] != null) {
					financeDetail.setBuildingId(Integer.parseInt(rows[12].toString()));
				}
			}
			financeDetail.setTradeDate(rows[10].toString());
			financeDetail.setTradeMoney(BigDecimal.valueOf(Double.valueOf(rows[11].toString())));
			financeDetail.setType(Integer.valueOf(rows[14].toString()));
			financeDetails.add(financeDetail);
		}
		return financeDetails;
	}
	
	public Map<Integer, List<FinanceTradeTypeVO>> getMonthTradeTypePercent(Integer year) {
		String sql = "select month(a.tradeDate), a.tradeType, sum(a.tradeMoney) from da_dafinancestatement a "
				+ "where year(a.tradeDate) = ? and a.landlordUser_user_id = ? and a.status = " + DaFinanceStatement.STATUS_VALID
				+ " GROUP BY month(a.tradeDate), a.tradeType";
		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		List result = em.createNativeQuery(sql)
				.setParameter(1, year)
				.setParameter(2, landlordUser.getOwnerUser().getId())
				.getResultList();
		List<FinanceTradeTypeVO> financeTradeTypes = new ArrayList<FinanceTradeTypeVO>(result.size());
		for (Object row : result) {
			Object[] rows = (Object[])row;
			FinanceTradeTypeVO financeTradeType = new FinanceTradeTypeVO();
			financeTradeType.setMonth(Integer.parseInt(rows[0].toString()));
			financeTradeType.setTradeType(Integer.parseInt(rows[1].toString()));
			financeTradeType.setTradeMoney(BigDecimal.valueOf(Double.parseDouble(rows[2].toString())));
			financeTradeTypes.add(financeTradeType);
		}
		
		BigDecimal[] amounts = new BigDecimal[13];
		for (int i = 0; i < amounts.length; i++) {
			amounts[i] = BigDecimal.valueOf(0);
		}
		for (FinanceTradeTypeVO financeTradeType : financeTradeTypes) {
			amounts[financeTradeType.getMonth()] = amounts[financeTradeType.getMonth()].add(financeTradeType.getTradeMoney());
		}
		for (FinanceTradeTypeVO financeTradeType : financeTradeTypes) {
			if (amounts[financeTradeType.getMonth()].compareTo(BigDecimal.ZERO) == 0) {
				financeTradeType.setPercent(BigDecimal.valueOf(0));
			} else {
				financeTradeType.setPercent(financeTradeType.getTradeMoney().divide(amounts[financeTradeType.getMonth()], 10, RoundingMode.HALF_UP));
			}
		}
		Map<Integer, List<FinanceTradeTypeVO>> resultMap = new HashMap<Integer, List<FinanceTradeTypeVO>>();
		int month = -1;
		List<FinanceTradeTypeVO> financeTradeTypeList = null;
		for (FinanceTradeTypeVO financeTradeType : financeTradeTypes) {
			if (month != financeTradeType.getMonth()) {
				financeTradeTypeList = new ArrayList<FinanceTradeTypeVO>(4);
				financeTradeTypeList.add(financeTradeType);
				month = financeTradeType.getMonth();
				resultMap.put(month, financeTradeTypeList);
			} else {
				financeTradeTypeList.add(financeTradeType);
			}
		}
		return resultMap;
	}
	
	public List<FinanceTradeTypeVO> getYearTradeTypePercent(Integer year) {
		String sql = "select year(a.tradeDate), a.tradeType, sum(a.tradeMoney) from da_dafinancestatement a "
				+ "where year(a.tradeDate) = ? and a.landlordUser_user_id = ? and a.status = " + DaFinanceStatement.STATUS_VALID
				+ " GROUP BY a.tradeType";
		LandlordUser landlordUser = landlordUserService.getLandlordUser();
		List result = em.createNativeQuery(sql)
				.setParameter(1, year)
				.setParameter(2, landlordUser.getOwnerUser().getId())
				.getResultList();
		List<FinanceTradeTypeVO> financeTradeTypes = new ArrayList<FinanceTradeTypeVO>(result.size());
		for (Object row : result) {
			Object[] rows = (Object[])row;
			FinanceTradeTypeVO financeTradeType = new FinanceTradeTypeVO();
			financeTradeType.setMonth(Integer.parseInt(rows[0].toString()));
			financeTradeType.setTradeType(Integer.parseInt(rows[1].toString()));
			financeTradeType.setTradeMoney(BigDecimal.valueOf(Double.parseDouble(rows[2].toString())));
			financeTradeTypes.add(financeTradeType);
		}
		
		BigDecimal amount = BigDecimal.valueOf(0);
		for (FinanceTradeTypeVO financeTradeType : financeTradeTypes) {
			amount = amount.add(financeTradeType.getTradeMoney());
		}
		for (FinanceTradeTypeVO financeTradeType : financeTradeTypes) {
			if (amount.compareTo(BigDecimal.ZERO) == 0) {
				financeTradeType.setPercent(BigDecimal.valueOf(0));
			} else {
				financeTradeType.setPercent(financeTradeType.getTradeMoney().divide(amount, 10, RoundingMode.HALF_UP));
			}
		}
		return financeTradeTypes;
	}
}
